package newnes.tests.fileloading;

import newnes.io.fileformats.*;
import newnes.io.memory.*;
import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public final class INESFileTests {
	
	
	static class INESFileTestFrame extends JFrame implements ActionListener, ItemListener{
		private INESFile file;
		private JPanel prgRomPanel;
		private JScrollPane scrollablePrgRomPane;
		private JPanel chrRomPanel;
		private JScrollPane scrollableChrRomPane;
		private JPanel headerPanel;
		private JLabel[] prgHexLabels;
		private JLabel[] chrHexLabels;
		private JComboBox prgBankList;
		private JComboBox chrBankList;
		private JMenu fileMenu;
		private JMenuItem open;
		private boolean isBankChange;
		private int chrRomSelect;
		private int prgRomSelect;
		private boolean ignore;
		private boolean recreate;
		private JLabel checksum;
		private JLabel mirroring;
		private JLabel filepath;
		private JLabel mapperNumber;
		private JLabel imageSize;
		public INESFileTestFrame(){
			createMenus();
			createContentPane();
		}
		
		public void createContentPane(){
			
			//createChrRomPanel();
			//createHeaderPanel();
			this.setLayout(new GridLayout(2,2));
			createPrgRomPanel();
			createChrRomPanel();
			createHeaderPanel();
		}
		
		private void createHeaderPanel(){
			if(file == null){
				checksum = new JLabel("CRC32: Undefined");
				mirroring = new JLabel("Mirroring Mode: Undefined");
				filepath = new JLabel("File Path: Undefined");
				mapperNumber = new JLabel("Mapper Number: Undefined");
				imageSize = new JLabel("Image Size: Undefined");
				JPanel temp = new JPanel();
				temp.setLayout(new GridLayout(7,1));
				temp.add(new JLabel("File Information"));
				temp.add(filepath);
				temp.add(checksum);
				temp.add(mapperNumber);
				temp.add(mirroring);
				temp.add(imageSize);
				this.add(temp);
			}else{
				filepath.setText("File Path: " + file.getPath());
				checksum.setText("CRC32: "+file.checksum().toUpperCase());
				INESHeader header = (INESHeader)file.getHeader();
				mirroring.setText("Mirroring Mode: "+header.getMirroringMode());
				String mapHexString = Integer.toString(header.getMapperNumber(),16);
				if(mapHexString.length() == 1){
					mapHexString = "0" + mapHexString;
				}
				mapperNumber.setText("Mapper Number: " + mapHexString.toUpperCase());
				imageSize.setText("Image Size: " + (file.getPrgRomSizeInBytes() + file.getChrRomSizeInBytes())/1024. + " kB.");
			}	
		}
		
		private void createMenus(){
			JMenuBar mainMenu = new JMenuBar();
			fileMenu = new JMenu("File");
			open = new JMenuItem("Open INES file...");
			open.addActionListener(this);
			fileMenu.add(open);
			mainMenu.add(fileMenu);
			this.setJMenuBar(mainMenu);
		}
		
		private void createPrgRomPanel(){
			if(file == null){
			
				prgRomPanel = new JPanel();
		    	//scrollablePrgRomPane = new JScrollPane();
		    	JPanel tempPanel = new JPanel();
		    	JPanel tempPanel2 = new JPanel();
				tempPanel2.setLayout(new GridLayout(1,256));
				prgRomPanel.setLayout(new BorderLayout());
				tempPanel2.add(new JLabel("PRG-ROM Bank"));
				prgBankList = new JComboBox();
				prgBankList.addItemListener(this);
				tempPanel2.add(prgBankList);
				for(int i = 0;i < 254;++i){
					tempPanel2.add(new JLabel("  "));
				}
				tempPanel.setLayout(new GridLayout(16,1024));
				String hexString = "00";
				prgHexLabels = new JLabel[16384];
				for(int i = 0;i < 16384;++i){
					prgHexLabels[i] = new JLabel(hexString);
					prgHexLabels[i].setBackground(Color.white);
					prgHexLabels[i].setForeground(Color.black);
					tempPanel.add(prgHexLabels[i]);
					Thread.yield();
				}
				prgRomPanel.add(tempPanel2, BorderLayout.NORTH);
				prgRomPanel.add(tempPanel, BorderLayout.CENTER);
				scrollablePrgRomPane = new JScrollPane(prgRomPanel); 
				this.add(scrollablePrgRomPane);
			}
			else{
				if(recreate){
					ignore = true;
					prgBankList.removeAllItems();
					for(int i = 0;i < file.getPrgRomSize();++i){
						prgBankList.addItem(i);
					}
					ignore = false;
				}
				Rom prgRom = file.getPrgRom(prgRomSelect);
				String hexString;
				for(int i = 0;i < prgHexLabels.length;++i){
					hexString = Integer.toString(prgRom.readFromMemory(i)&0xFF,16);
					if(hexString.length() == 1){
						hexString = "0" + hexString;
					}
					prgHexLabels[i].setText(hexString.toUpperCase());
				}
			}
		}
		
		private void createChrRomPanel(){
			if(file == null){
			
				chrRomPanel = new JPanel();
		    	//scrollableChrRomPane = new JScrollPane();
		    	JPanel tempPanel = new JPanel();
		    	JPanel tempPanel2 = new JPanel();
				tempPanel2.setLayout(new GridLayout(1,256));
				chrRomPanel.setLayout(new BorderLayout());
				tempPanel2.add(new JLabel("CHR-ROM Bank"));
				chrBankList = new JComboBox();
				chrBankList.addItemListener(this);
				tempPanel2.add(chrBankList);
				for(int i = 0;i < 254;++i){
					tempPanel2.add(new JLabel("  "));
				}
				tempPanel.setLayout(new GridLayout(8,1024));
				String hexString = "00";
				chrHexLabels = new JLabel[8192];
				for(int i = 0;i < 8192;++i){
					chrHexLabels[i] = new JLabel(hexString);
					chrHexLabels[i].setBackground(Color.white);
					chrHexLabels[i].setForeground(Color.black);
					tempPanel.add(chrHexLabels[i]);
					Thread.yield();
				}
				chrRomPanel.add(tempPanel2, BorderLayout.NORTH);
				chrRomPanel.add(tempPanel, BorderLayout.CENTER);
				scrollableChrRomPane = new JScrollPane(chrRomPanel); 
				this.add(scrollableChrRomPane);
			}
			else{
				if(recreate){
					ignore = true;
					chrBankList.removeAllItems();
					for(int i = 0;i < file.getChrRomSize();++i){
						chrBankList.addItem(i);
					}
					ignore = false;
				}
				Rom chrRom = file.getChrRom(chrRomSelect);
				if(chrRom == null){
					return;
				}
				String hexString;
				for(int i = 0;i < chrHexLabels.length;++i){
					hexString = Integer.toString(chrRom.readFromMemory(i)&0xFF,16);
					if(hexString.length() == 1){
						hexString = "0" + hexString;
					}
					chrHexLabels[i].setText(hexString.toUpperCase());
				}
			}
		}
		
		public void actionPerformed(ActionEvent e){
			//Handle open button action.
			JFileChooser fc = new JFileChooser();
    		if (e.getSource() == open) {
      			int returnVal = fc.showOpenDialog(this);

      			if (returnVal == JFileChooser.APPROVE_OPTION) {
        			file = new INESFile(fc.getSelectedFile().getAbsolutePath());
        			try{
        				file.load();
        			}catch(IOException ioex){
        				return;
        			}
        			chrRomSelect = 0;
        			prgRomSelect = 0;
        			recreate = true;
        			createContentPane();
        			recreate = false;
      			} 
    		}
		}
		
		public void itemStateChanged(ItemEvent e){
			if(e.getSource() == chrBankList && e.getStateChange() == ItemEvent.SELECTED && !ignore){
				if(e.getItem() instanceof Integer){
					chrRomSelect = (Integer)e.getItem();
					createChrRomPanel();
				}
			}
			if(e.getSource() == prgBankList && e.getStateChange() == ItemEvent.SELECTED && !ignore){
				if(e.getItem() instanceof Integer){
					prgRomSelect = (Integer)e.getItem();
					createPrgRomPanel();
				}
			}
		}
	}
	/**
	 * Method main
	 *
	 *
	 * @param args
	 *
	 */
	public static void main(String[] args) throws IOException {
		JFrame test = new INESFileTestFrame(); 
		test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		test.setSize(800,600);
		test.setVisible(true);
	}	
}
